using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.Security;
using System.Web;
using System.Xml;

using Warcraft.Armory;

namespace Warcraft.Armory.Guild
{

    public sealed class WarcraftArmoryGuildSearchException : Exception
    {

        public WarcraftArmoryGuildSearchException(string message) : base(message)
        {
        }

    }

    public sealed class WarcraftArmoryGuildSearch
    {

        private WarcraftArmory armory;

        public WarcraftArmoryGuildSearch(WarcraftArmory armory)
        {
            this.armory = armory;
        }

        public WarcraftArmoryGuildSearchResults Find(string query)
        {
            // Create results
            WarcraftArmoryGuildSearchResults results = new WarcraftArmoryGuildSearchResults(armory);

            // Set up base search url
            string url = "search.xml?searchQuery={query}&searchType=guilds";

            // Replace query placeholder
            url = url.Replace("{query}",HttpUtility.UrlEncode(query));

            // Dispatch request
            HttpWebResponse response = armory.Request(url);

            // Create XML document
            XmlDocument document = new XmlDocument();

            // Load response into document
            document.Load(response.GetResponseStream());

            // Get list of guild nodes
            XmlNodeList nodes = document.SelectNodes("/page/armorySearch/searchResults/guilds/guild");

            for (int i = 0; i < nodes.Count; i++) {
                // Get node
                XmlNode node = nodes[i];

                // Make sure it's a guild node, if not simply skip
                if (node.LocalName.ToLower() != "guild") continue;

                // Get node attributes
                string battlegroup = node.Attributes["battleGroup"].Value;
                WarcraftArmoryFaction faction = (WarcraftArmoryFaction)int.Parse(node.Attributes["factionId"].Value);
                string realm = node.Attributes["realm"].Value;
                string guildname = node.Attributes["name"].Value;
                
                // Create result
                WarcraftArmoryGuildSearchResult result = new WarcraftArmoryGuildSearchResult(armory,battlegroup,faction,guildname,realm);

                // Add result to results
                results.Add(result);
            }

            // Return results
            return results;
        }

    }

    public sealed class WarcraftArmoryGuildSearchResults : WarcraftArmorySearchResults, ICollection, IEnumerable
    {

        private WarcraftArmory armory;
        private ArrayList list;

        internal WarcraftArmoryGuildSearchResults(WarcraftArmory armory)
        {
            this.armory = armory;
            list = new ArrayList();
        }

        /* Methods */

        internal void Add(WarcraftArmoryGuildSearchResult result)
        {
            list.Add(result);
        }

        public IEnumerator GetEnumerator()
        {
            return list.GetEnumerator();
        }

        public void CopyTo(Array array, int arrayIndex)
        {
            list.CopyTo(array,arrayIndex);
        }

        /* Properties */

        public object SyncRoot
        {
            get {
                return this;
            }
        }

        public bool IsSynchronized
        {
            get {
                return false;
            }
        }

        public int Count
        {
            get {
                return list.Count;
            }
        }

        public WarcraftArmoryGuildSearchResult this[int index]
        {
            get {
                return (WarcraftArmoryGuildSearchResult)list[index];
            }
        }

    }

    public class WarcraftArmoryGuildSearchResult
    {

        private WarcraftArmory armory;
        private string battlegroup;
        private WarcraftArmoryFaction faction;
        private string guildname;
        private string realm;

        internal WarcraftArmoryGuildSearchResult(WarcraftArmory armory, string battlegroup, WarcraftArmoryFaction faction, string guildname, string realm)
        {
            this.armory = armory;
            this.battlegroup = battlegroup;
            this.faction = faction;
            this.guildname = guildname;
            this.realm = realm;
        }

        /* Methods */

        public WarcraftArmoryGuild ToGuild()
        {
            return new WarcraftArmoryGuild(armory,realm,guildname);
        }

        /* Properties */

        public string Battlegroup
        {
            get {
                return battlegroup;
            }
        }

        public WarcraftArmoryFaction Faction
        {
            get {
                return faction;
            }
        }

        public string GuildName
        {
            get {
                return guildname;
            }
        }

        public string Realm
        {
            get {
                return realm;
            }
        }

    }

}
